package com.dbflow5.query.list;

import com.dbflow5.BaseUnitTest;
import com.dbflow5.config.FlowManager;
import com.dbflow5.database.FlowCursor;
import com.dbflow5.models.SimpleTestModels.SimpleModel;
import com.dbflow5.query.ModelQueriable;
import com.dbflow5.query.SQLite;

import com.dbflow5.structure.Model;
import org.junit.Test;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;

import static org.junit.Assert.assertEquals;

public class FlowCursorListTest extends BaseUnitTest {
    @Test
    public void validateCursorPassed() {
        FlowManager.databaseForTable(SimpleModel.class, db -> {
            FlowCursor cursor = SQLite.select().from(SimpleModel.class).cursor(db);
            FlowCursorList<SimpleModel> list = new FlowCursorList.Builder<>(SQLite.select().from(SimpleModel.class), db)
                .cursor(cursor)
                .build();

            assertEquals(cursor, list.cursor());
            return null;
        });
    }

    @Test
    public void validateModelQueriable() {
        FlowManager.databaseForTable(SimpleModel.class, db -> {
            ModelQueriable<SimpleModel> modelQueriable = SQLite.select().from(SimpleModel.class);
            FlowCursorList<SimpleModel> list = new FlowCursorList.Builder<>(modelQueriable, db)
                    .build();

            assertEquals(modelQueriable, list.modelQueriable);
            return null;
        });

    }

    @Test
    public void validateGetAll() {
        FlowManager.databaseForTable(SimpleModel.class, db -> {
            for(int i=0;i<=9;i++) {
                Model.save(SimpleModel.class, new SimpleModel(String.valueOf(i)), db);
            }

            FlowCursorList<SimpleModel> list = SQLite.select().from(SimpleModel.class).cursorList(db);
            List<SimpleModel> all = list.all();
            assertEquals(list.count(), all.size());
            return null;
        });
    }

    @Test
    public void validateCursorChange() {
        FlowManager.databaseForTable(SimpleModel.class, db -> {
            for(int i=0;i<=9;i++) {
                Model.save(SimpleModel.class, new SimpleModel(String.valueOf(i)), db);
            }
            FlowCursorList<SimpleModel> list = SQLite.select().from(SimpleModel.class).cursorList(db);

            AtomicReference<FlowCursorList<SimpleModel>> cursorListFound = new AtomicReference<>();
            AtomicInteger count = new AtomicInteger();

            Function<FlowCursorList<SimpleModel>, Void> listener = simpleModels -> {
                cursorListFound.set(simpleModels);
                count.getAndIncrement();
                return null;
            };

            list.addOnCursorRefreshListener(listener);
            assertEquals(10, list.count());
            Model.save(SimpleModel.class, new SimpleModel("10"), db);
            list.refresh();
            assertEquals(11, list.count());

            assertEquals(list, cursorListFound.get());

            list.removeOnCursorRefreshListener(listener);

            list.refresh();
            assertEquals(1, count.get());
            return null;
        });
    }

}
